package com.gcloud.mesh.sm;
import java.io.UnsupportedEncodingException;
import java.security.Security;
import java.util.Arrays;

import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;

public class SM3Util {
   private static final String ENCODING = "UTF-8";
    static {
        Security.addProvider(new BouncyCastleProvider());
    }
    
    public static String encrypt(String paramStr){
        // 将返回的hash值转换成16进制字符串
        String resultHexString = "";
        try {
            // 将字符串转换成byte数组
            //byte[] srcData = paramStr.getBytes(ENCODING);
            byte[] srcData = ByteUtils.fromHexString(paramStr);
            // 调用hash()
            byte[] resultHash = hash(srcData);
            // 将返回的hash值转换成16进制字符串
            resultHexString = ByteUtils.toHexString(resultHash);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultHexString;
    }
    

    public static byte[] hash(byte[] srcData) {
	    SM3Digest digest = new SM3Digest();
	    digest.update(srcData, 0, srcData.length);
	    byte[] hash = new byte[digest.getDigestSize()];
	    digest.doFinal(hash, 0);
	    return hash;
	}
    

	public static byte[] hmac(byte[] key, byte[] srcData) {
	    KeyParameter keyParameter = new KeyParameter(key);
	    SM3Digest digest = new SM3Digest();
	    HMac mac = new HMac(digest);
	    mac.init(keyParameter);
	    mac.update(srcData, 0, srcData.length);
	    byte[] result = new byte[mac.getMacSize()];
	    mac.doFinal(result, 0);
	    return result;
	}


	/**
	 * 判断源数据与加密数据是否一致
	 * @explain 通过验证原数组和生成的hash数组是否为同一数组，验证2者是否为同一数据
	 * @param srcStr
	 *            原字符串
	 * @param sm3HexString
	 *            16进制字符串
	 * @return 校验结果
	 */

	public static boolean verify(String srcStr, String sm3HexString) {
	    boolean flag = false;
	    try {
	        byte[] srcData = srcStr.getBytes(ENCODING);
	        byte[] sm3Hash = ByteUtils.fromHexString(sm3HexString);
	        byte[] newHash = hash(srcData);
	        if (Arrays.equals(newHash, sm3Hash))
	            flag = true;
	    } catch (UnsupportedEncodingException e) {
	        e.printStackTrace();
	    }
	    return flag;
	}
	
	public static void main(String[] args) {
	    // 测试二：json
	    String json = "763AFC537F7876C2D0B59FDB68D762E90CEFD222BB358D0D6931867CE26538649BE3579A4004483EA5D84D005063F76FB1CE7E5F2F933B5ED757A718182F383C4D58291A6A5D8D07C081F66806031539093362D854883A8874F7B919925DABC74C173E2162F07E6780E311FF0AEF059AE620303DECB6289E97F72C018723C471";
	    String hex = SM3Util.encrypt(json);
	    System.out.println(hex);// 0b0880f6f2ccd817809a432420e42b66d3772dc18d80789049d0f9654efeae5c
	    // 验证加密后的16进制字符串与加密前的字符串是否相同
	    boolean flag = SM3Util.verify(json, hex);
	    System.out.println(flag);// true
	}

}
